package org.oslims.client.uicomponents.editbox;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.oslims.client.uicomponents.SelectionColumn;
import org.oslims.client.uicomponents.inputfields.DateInputField;
import org.oslims.client.uicomponents.inputfields.DropDownInputField;
import org.oslims.client.uicomponents.inputfields.InputField;
import org.oslims.client.uicomponents.inputfields.RichTextInputField;
import org.oslims.client.uicomponents.inputfields.TextInputField;
import org.oslims.domain.Mixture;
import org.oslims.domain.MixtureComponent;

import com.google.gwt.cell.client.EditTextCell;
import com.google.gwt.cell.client.FieldUpdater;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.cellview.client.TextColumn;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasHTML;
import com.google.gwt.user.client.ui.HasText;
import com.google.gwt.user.client.ui.HasValue;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.view.client.MultiSelectionModel;

public class EditMixtureBox {

	final DialogBox editSampleBox = new DialogBox(false, true);
	final VerticalPanel editSampleBoxPanel = new VerticalPanel();

	protected Map<String, InputField> inputFields = new HashMap<String, InputField>();

	final HorizontalPanel buttonLine = new HorizontalPanel();
	final Button saveButton = new Button("Save");
	final Button cancelButton = new Button("Cancel");

	final TextInputField originField = new TextInputField("origin", "Origin: ", "120px", "200px");
	final RichTextInputField descriptionField = new RichTextInputField("description", "Description: ", "120px", "400px");
	final DateInputField samplingDateField = new DateInputField("samplingTime", "Sampling Date: ", "120px", "200px");
	final DropDownInputField sampleTypeField = new DropDownInputField("sampleType", "Sample Type: ", "120px", "200px");

	final Label compositionLabel = new Label("Composition:");
	final CellTable<MixtureComponent> compositionTable = new CellTable<MixtureComponent>(100);
	final MultiSelectionModel<MixtureComponent> sm = new MultiSelectionModel<MixtureComponent>();
	final Label sumLabel = new Label("0");
	final Label sumLabelPercentage = new Label("%");
	final HorizontalPanel compositionArea = new HorizontalPanel();
	final VerticalPanel compositionComponents = new VerticalPanel();
	final HorizontalPanel compositionButtonLine = new HorizontalPanel();
	final Button addMixtureComponent = new Button("Add");
	final Button removeMixtureComponent = new Button("X");
	final SearchSamplesBox searchSamplesBox = new SearchSamplesBox();

	Mixture editedMixture;

	String editedType;

	public EditMixtureBox() {

		editSampleBoxPanel.add(originField);
		inputFields.put(originField.getFieldName(), originField);

		editSampleBoxPanel.add(descriptionField);
		inputFields.put(descriptionField.getFieldName(), descriptionField);

		editSampleBoxPanel.add(samplingDateField);
		inputFields.put(samplingDateField.getFieldName(), samplingDateField);

		editSampleBoxPanel.add(sampleTypeField);
		inputFields.put(sampleTypeField.getFieldName(), sampleTypeField);

		editSampleBoxPanel.add(new HTML("<br/>"));

		compositionLabel.setWidth("120px");
		compositionArea.add(compositionLabel);

		SelectionColumn<MixtureComponent> selColumn = new SelectionColumn<MixtureComponent>(sm);
		compositionTable.addColumn(selColumn);

		compositionTable.addColumn(new TextColumn<MixtureComponent>() {

			@Override
			public String getValue(MixtureComponent object) {
				return object.getSample().getCode();
			}
		}, "Code");

		compositionTable.addColumn(new TextColumn<MixtureComponent>() {

			@Override
			public String getValue(MixtureComponent object) {
				return object.getSample().getSampleType().toString();
			}
		}, "Sample Type");

		compositionTable.addColumn(new TextColumn<MixtureComponent>() {

			@Override
			public String getValue(MixtureComponent object) {
				return object.getSample().getOrigin();
			}
		}, "Origin");

		Column<MixtureComponent, String> amountCol = new Column<MixtureComponent, String>(new EditTextCell()) {

			@Override
			public String getValue(MixtureComponent object) {
				return object.getAmmount().toString();
			}

		};

		compositionTable.addColumn(amountCol, "%");

		amountCol.setFieldUpdater(new FieldUpdater<MixtureComponent, String>() {

			@Override
			public void update(int index, MixtureComponent object, String value) {

				try {
					Double d = Double.parseDouble(value);
					object.setAmmount(d);
					refreshSum();
				} catch (Exception e) {
					value = "";
				}

			}
		});

		compositionTable.setSelectionModel(sm);
		// compositionTable.setSelectionEnabled(true);

		compositionComponents.add(compositionTable);
		HorizontalPanel hp = new HorizontalPanel();
		hp.add(sumLabel);
		hp.add(sumLabelPercentage);
		compositionComponents.add(hp);

		compositionButtonLine.add(addMixtureComponent);
		compositionButtonLine.add(removeMixtureComponent);
		compositionComponents.add(compositionButtonLine);

		compositionArea.add(compositionComponents);

		editSampleBoxPanel.add(compositionArea);

		editSampleBoxPanel.add(new HTML("<br/>"));

		buttonLine.add(saveButton);
		buttonLine.add(cancelButton);

		// Add the save and cancel buttons
		editSampleBoxPanel.add(buttonLine);

		editSampleBox.add(editSampleBoxPanel);
	}

	protected void refreshSum() {

		Double sum = 0d;
		for (MixtureComponent mc : compositionTable.getDisplayedItems()) {
			if (mc != null)
				if (mc.getAmmount() != null)
					sum += mc.getAmmount();
		}

		sumLabel.setText(sum.toString());
	}

	public void hide() {
		editSampleBox.hide();
	}

	public void clear() {
		editedMixture = null;
		originField.getInputField().setValue("");
		descriptionField.getInputHtml().setHTML("");
		// sampleTypeField.getInputBox().setSelectedIndex(-1);
		samplingDateField.getInputField().setValue(null);
		editSampleBox.setText("Create new Mixture");
		editSampleBox.center();
		compositionTable.setDataSize(0, true);
		compositionTable.setData(0, 0, new ArrayList<MixtureComponent>());
		compositionTable.redraw();
		sumLabel.setText("0");
	}

	public void showNew() {
		this.clear();
		this.clearAllErrors();
	}

	public void showEdit(Mixture mixture) {
		this.clear();
		this.clearAllErrors();

		editedMixture = mixture;
		originField.getInputField().setValue(mixture.getOrigin());
		descriptionField.getInputHtml().setHTML(mixture.getDescription());
		if (mixture.getSamplingTime() != null)
			samplingDateField.getInputField().setValue(mixture.getSamplingTime());

		GWT.log("Mixture Components Size: " + mixture.getComponents().size());

		compositionTable.setDataSize(mixture.getComponents().size(), true);
		compositionTable.setData(0, mixture.getComponents().size(), mixture.getComponents());
		sm.getSelectedSet().clear();
		compositionTable.redraw();

		refreshSum();

		editSampleBox.setText("Edit Mixture");
		editSampleBox.center();
	}

	public void showError(String fieldName, String message) {
		GWT.log(fieldName);
		inputFields.get(fieldName).showError(message);
	}

	public void clearError(String fieldName) {
		inputFields.get(fieldName).clearError();
	}

	public void clearAllErrors() {
		for (InputField inputField : inputFields.values()) {
			inputField.clearError();
		}
	}

	public HasValue<String> getOrigin() {
		return originField.getInputField();
	}

	public HasHTML getDescription() {
		return descriptionField.getInputHtml();
	}

	public HasValue<Date> getSamplingTime() {
		return samplingDateField.getInputField();
	}

	public DropDownInputField getSampleType() {
		return sampleTypeField;
	}

	public HasClickHandlers getSaveButton() {
		return saveButton;
	}

	public HasClickHandlers getCancelButton() {
		return cancelButton;
	}

	public Mixture getMixture() {
		return editedMixture;
	}

	public CellTable<MixtureComponent> getCompositionTable() {
		return compositionTable;
	}

	public HasClickHandlers getAddComponentButton() {
		return addMixtureComponent;
	}

	public HasClickHandlers getRemoveComponentButton() {
		return removeMixtureComponent;
	}

	public HasText getSumField() {
		return sumLabel;
	}

	public void removeSelectedComponents() {

		if (sm.getSelectedSet().size() == 0)
			return;

		List<MixtureComponent> newList = compositionTable.getDisplayedItems();

		GWT.log(newList.removeAll(sm.getSelectedSet()) + "");
		compositionTable.setDataSize(newList.size(), true);
		compositionTable.setData(0, newList.size(), newList);
		compositionTable.redraw();
		sm.getSelectedSet().clear();
		refreshSum();
	}

	public SearchSamplesBox getSearchSamplesBox() {
		return searchSamplesBox;
	}
}
